#include "SPI.hpp"
#include <cstring>
#include <cstdio>


SPI::SPI() = default;

SPI::SPI(spi_host_device_t host, int sckPin, int mosiPin, int misoPin)
    : _host(host), _sckPin(sckPin), _mosiPin(mosiPin), _misoPin(misoPin), _spi(nullptr) {}

SPI::~SPI() {
    if (_spi) {
        spi_bus_remove_device(_spi);
    }
}


void SPI::init() const {
    spi_bus_config_t buscfg = { };
    buscfg = {
        .mosi_io_num = _mosiPin,
        .miso_io_num = _misoPin,
        .sclk_io_num = _sckPin,
        .quadwp_io_num = -1,
        .quadhd_io_num = -1,
        .max_transfer_sz = 160 * 80 * 2
    };

    // 初始化SPI总线
    if (const esp_err_t ret = spi_bus_initialize(_host, &buscfg, SPI_DMA_CH_AUTO); ret != ESP_OK) {
        printf("Failed to initialize SPI bus: %s\n", esp_err_to_name(ret));
        return;
    }
    printf("SPI display initialized!\n");
}

void SPI::spiWriteCmd(spi_device_handle_t handle, uint8_t cmd) {
    spi_transaction_t t = {0};
    t.length = 8; /* 要传输的位数 一个字节 8 位 */
    t.tx_buffer = &cmd; /* 将命令填充进去 */
    if (const esp_err_t ret = spi_device_polling_transmit(handle, &t); ret != ESP_OK) {
        printf("Failed to write cmd: %s\n", esp_err_to_name(ret));
        return;
    }
}

void SPI::spiWriteData(spi_device_handle_t handle, const uint8_t *data, int len) {
    esp_err_t ret;
    spi_transaction_t t = {0};
    if (len == 0) {
        return; /* 长度为 0 没有数据要传输 */
    }
    t.length = len * 8; /* 要传输的位数 一个字节 8 位 */
    t.tx_buffer = data; /* 将命令填充进去 */
    ret = spi_device_polling_transmit(handle, &t); /* 开始传输 */
    if (ret != ESP_OK) {
        printf("Failed to write cmd: %s\n", esp_err_to_name(ret));
        return;
    }
}